<template>
  <div class="app-container">
    <div class="filter-container">
      <el-form ref="dataForm"
               :model="inputForm"
               inline
               :rules="rules"
               label-position="left">
        <el-form-item label="数据源"
                      prop="datasourceId">
          <el-select v-model="inputForm.datasourceId"
                     placeholder="请选择数据源"
                     class="filter-item"
                     style="width: 130px ;margin-right: 10px;"
                     @change="changeDateSource">
            <el-option v-for="item in dataSourceOptions"
                       :key="item.value"
                       :label="item.label"
                       :value="item.value"/>
          </el-select>
        </el-form-item>
        <el-form-item label="方案"
                      prop="planId">
          <el-select v-model="inputForm.planId"
                     placeholder="请选择方案"
                     class="filter-item"
                     style="width: 130px; margin-right: 20px;">
            <el-option v-for="item in planTypeOptions"
                       :key="item.value"
                       :label="item.label"
                       :value="item.value"/>
          </el-select>
        </el-form-item>
        <el-form-item >
          <el-button class="filter-item"
                     style="margin-left: 10px;"
                     type="warning"
                     size="small"
                     @click="toggleSelection()">取消选择
          </el-button>
          <el-button class="filter-item"
                     style="margin-left: 10px;"
                     type="primary"
                     size="small"
                     icon="el-icon-plus"
                     @click="generatorCodeByPlan">
            生成代码
          </el-button>
        </el-form-item>
      </el-form>
    </div>
    <el-table :key="tableKey"
              ref="multipleTable"
              v-loading="listLoading"
              :data="list"
              border
              fit
              highlight-current-row
              style="width: 100%;"
              @sort-change="sortChange"
              @selection-change="handleSelectionChange">
      <el-table-column type="selection"
                       width="55"/>
      <el-table-column type="index"
                       label="序号"
                       width="
                       50px"/>
      <el-table-column label="表名"
                       align="center">
        min-width="150px">
        <template slot-scope="{row}">
          <span>{{ row.tableName }}</span>
        </template>
      </el-table-column>
      <el-table-column label="表注释">
        <template slot-scope="{row}">
          <span>{{ row.tableComment }}</span>
        </template>
      </el-table-column>
      <el-table-column label="操作"
                       align="center"
                       width="400px"
                       class-name="small-padding fixed-width">
        <template slot-scope="{row,$index}">
          <el-button type="primary"
                     size="mini"
                     @click="tableDetails(row)">
            详情
          </el-button>
          <el-button type="primary"
                     size="mini"
                     @click="previewCodeMethod(row)">
            预览
          </el-button>
        </template>
      </el-table-column>
    </el-table>
    <!--表结构信息展示表单 -->
    <!--el-dialog 对话框 -->
    <el-dialog :title="textMap[dialogStatus]"
               :visible.sync="dialogFormVisible">
      <el-table :data="gridData">
        <el-table-column property="name"
                         label="字段名"/>
        <el-table-column property="comment"
                         label="注释"/>
        <el-table-column property="type"
                         label="类型"/>
        <el-table-column property="isId"
                         label="是否主键"/>
      </el-table>
    </el-dialog>
    <!--生成代码对话框 -->
    <el-dialog title="生成代码"
               :visible.sync="dialogGenFormVisible">
      <el-form :model="genForm">
        <el-form-item label="活动名称"
                      :label-width="formLabelWidth">
          <el-input v-model="genForm.name"
                    autocomplete="off"/>
        </el-form-item>
      </el-form>
      <div slot="footer"
           class="dialog-footer">
        <el-button @click="dialogFormVisible = false">预览</el-button>
        <el-button type="primary"
                   @click="generatorCodeByPlan">直接生成
        </el-button>
      </div>
    </el-dialog>
    <!-- 预览界面 -->
    <el-dialog :title="preview.title"
               :visible.sync="preview.open"
               width="80%"
               top="5vh"
               append-to-body
               class="scrollbar">
      <el-tabs v-model="preview.activeName">
        <!--复制-->
        <el-tab-pane v-for="(value, key,) in preview.data"
                     :key="key"
                     :label="key.substring(key.lastIndexOf('/')+1,key.indexOf('.ftl'))"
                     :name="key.substring(key.lastIndexOf('/')+1,key.indexOf('.ftl'))">
          <!--复制-->
          <el-link v-clipboard:copy="value"
                   v-clipboard:success="clipboardSuccess"
                   type="success"
                   :underline="false"
                   icon="el-icon-document-copy"
                   style="float:right">复制
          </el-link>
          <pre><code class="hljs" v-html="highlightedCode(value, key)"/></pre>
        </el-tab-pane>
      </el-tabs>
    </el-dialog>
  </div>
</template>

<script>
import {tableFiledInfo, list, tableList} from '@/api/datasource'
import {listAllPlan} from '@/api/plan'
import {generatorCode, previewCode} from '@/api/generator'
import clipboard from '@/directive/clipboard/index.js' // use clipboard by v-directive
import waves from '@/directive/waves' // waves directive
import hljs from 'highlight.js' // 导入代码高亮文件
import 'highlight.js/styles/github.css'
hljs.registerLanguage('java', require('highlight.js/lib/languages/java'))
hljs.registerLanguage('xml', require('highlight.js/lib/languages/xml'))
hljs.registerLanguage('html', require('highlight.js/lib/languages/xml'))
hljs.registerLanguage('vue', require('highlight.js/lib/languages/xml'))
hljs.registerLanguage('javascript', require('highlight.js/lib/languages/javascript'))
hljs.registerLanguage('sql', require('highlight.js/lib/languages/sql'))
const yesOrNoOptions = [
  { value: 1, label: '是' },
  { value: 0, label: '否' }
]
// 遍历选项，获取数字对应的字符串值
const yesOrNoTypeKeyValue = yesOrNoOptions.reduce((acc, cur) => {
  acc[cur.value] = cur.label
  return acc
}, {})
export default {
  name: 'ComplexTable',
  directives: {waves, clipboard},
  filters: {
    statusFilter(status) {
      const statusMap = {
        published: 'success',
        draft: 'info',
        deleted: 'danger'
      }
      return statusMap[status]
    },
    typeFilter(type) {
      return calendarTypeKeyValue[type]
    },
    // 是否值过滤器
    yesOrNoFilter (type) {
      return yesOrNoTypeKeyValue[type]
    }
  },
  data() {
    return {
      yesOrNoOptions,
      yesOrNoTypeKeyValue,
      priviewParam: {
        datasourceId: undefined,
        planId: undefined,
        tableNameList: []
      },
      formLabelWidth: '120px',
      planId: undefined,
      tableKey: 0,
      list: null,
      total: 0,
      listLoading: true,
      gridData: [],
      dialogTableVisible: false,
      dialogFormVisible: false,
      dialogGenFormVisible: false,
      listQuery: {
        dbTypeName: undefined,
        id: undefined,
        name: undefined
      },
      generatorCodeParam: {
        datasourceId: undefined,
        planId: undefined,
        tableNameList: []
      },
      // 预览参数
      preview: {
        open: false,
        title: '代码预览',
        data: {},
        activeName: 'controller.java'
      },
      inputForm: {
        datasourceId: undefined,
        planId: undefined,
        date2: '',
        delivery: false,
        type: [],
        resource: '',
        desc: ''
      },
      genForm: {
        name: '',
        region: '',
        date1: '',
        date2: '',
        delivery: false,
        type: [],
        resource: '',
        desc: ''
      },
      multipleSelection: [],
      dataSourceOptions: [],
      planTypeOptions: [],
      importanceOptions: [1, 2, 3],
      sortOptions: [{label: 'ID Ascending', key: '+id'}, {label: 'ID Descending', key: '-id'}],
      statusOptions: ['published', 'draft', 'deleted'],
      showReviewer: false,
      temp: {
        name: '',
        url: '',
        username: '',
        password: '',
        remark: ''
      },
      tableInfo: {},
      dialogStatus: '',
      textMap: {
        update: '详情'
      },
      dialogPvVisible: false,
      pvData: [],
      rules: {
        // type: [{ required: true, message: 'type is required', trigger: 'change' }],
        // timestamp: [{ type: 'date', required: true, message: 'timestamp is required', trigger: 'change' }],
        planId: [{required: true, message: '方案不能为空', trigger: 'blur'}],
        datasourceId: [{required: true, message: '数据源不能为空', trigger: 'blur'}]
      },
      downloadLoading: false
    }
  },
  created() {
    this.getList(),
      this.getDataSource(),
      this.getAllPlan()
  },
  methods: {
    toggleSelection(rows) {
      if (rows) {
        rows.forEach(row => {
          this.$refs.multipleTable.toggleRowSelection(row);
        });
      } else {
        this.$refs.multipleTable.clearSelection();
      }
    },
    // 高亮显示
    highlightedCode(code, key) {
      const vmName = key.substring(key.lastIndexOf('/') + 1, key.indexOf('.ftl'))
      const language = vmName.substring(vmName.indexOf('.') + 1, vmName.length)
      const result = hljs.highlight(language, code || '', true)
      return result.value || '&nbsp;'
    },
    //  复制代码成功
    clipboardSuccess() {
      this.$message({
        message: '复制成功',
        type: 'success',
        duration: 1000
      })
    },
    // 预览
    previewCodeMethod(row) {
      this.$refs['dataForm'].validate((valid) => {if (valid) {
        this.priviewParam.datasourceId = this.inputForm.datasourceId
        this.priviewParam.planId = this.inputForm.planId
        this.priviewParam.tableName = row.tableName
        this.preview.open = true
        this.preview.data = {}
        previewCode(this.priviewParam).then(response => {
          // 预览
          this.preview.data = response.data
          this.preview.activeName = 'controller.java'
        })
      }})
    },
    handleSelectionChange(val) {
      this.multipleSelection = val
    },
    // 切换数据源
    changeDateSource() {
      this.listLoading = true
      tableList(this.inputForm.datasourceId).then(response => {
        this.list = response.data
        // Just to simulate the time of the request
        setTimeout(() => {
          this.listLoading = false
        }, 200)
      })
    },
    // 使用方案生成代码
    generatorCodeByPlan() {
      // 检查数据源、方案、表、是否选择
      this.$refs['dataForm'].validate((valid) => {
        if (valid) {
          this.generatorCodeParam.datasourceId = this.inputForm.datasourceId
          this.generatorCodeParam.planId =  this.inputForm.planId
          this.generatorCodeParam.tableNameList = []
          if (this.multipleSelection.length <=0){
            this.$message({
              message: '请选择需要生成的表',
              type: 'error',
              duration: 1000
            })
            return
          }
          this.multipleSelection.forEach(row => {
            this.generatorCodeParam.tableNameList.push(row.tableName)
          })
          generatorCode(this.generatorCodeParam).then(response => {
            this.dataSourceOptions = response.data.map((item, index) => ({
              value: item.id,
              label: item.name
            }))
          })
        }
      })
    },
    getDataSource() {
      list().then(response => {
        this.dataSourceOptions = response.data.map((item, index) => ({
          value: item.id,
          label: item.name
        }))
      })
    },
    getList() {
      this.listLoading = false
      this.list = []
    },
    handleFilter() {
      this.listQuery.page = 1
      this.getList()
    },
    handleModifyStatus(row, status) {
      this.$message({
        message: '操作Success',
        type: 'success'
      })
      row.status = status
    },
    sortChange(data) {
      const {prop, order} = data
      if (prop === 'id') {
        this.sortByID(order)
      }
    },
    sortByID(order) {
      if (order === 'ascending') {
        this.listQuery.sort = '+id'
      } else {
        this.listQuery.sort = '-id'
      }
      this.handleFilter()
    },
    resetTemp() {
      this.temp = {
        name: '',
        url: '',
        username: '',
        password: '',
        remark: ''
      }
    },
    // 生成代码
    getAllPlan() {
      // 查询所有方案
      listAllPlan().then(response => {
        this.planTypeOptions = response.data.map((item, index) => ({
          value: item.id,
          label: item.name
        }))
      })
    },
    // 查看表结构详情
    tableDetails(row) {
      this.dialogStatus = 'update'
      this.dialogFormVisible = true
      this.tableInfo.tableName = row.tableName
      this.tableInfo.id = this.inputForm.datasourceId
      tableFiledInfo(this.tableInfo).then(response => {
        this.gridData = response.data
        // Just to simulate the time of the request
        setTimeout(() => {
          this.listLoading = false
        }, 200)
      })
    }
  }
}
</script>
